package com.yuexunit.finance.member.action.v1;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import com.yuexunit.account.action.v2.AccountActionApi;
import com.yuexunit.account.action.v2.AccountActionWebApi;
import com.yuexunit.account.action.v2.model.AccountAlias;
import com.yuexunit.account.action.v2.model.AccountId;
import com.yuexunit.account.action.v2.model.AccountNameType;
import com.yuexunit.core.BusinessException;
import com.yuexunit.finance.common.util.CollectionUtils;
import com.yuexunit.finance.common.util.DateUtils;
import com.yuexunit.finance.context.FinanceSessionContext;
import com.yuexunit.finance.member.action.v1.dto.LogisticsClerkCastor;
import com.yuexunit.finance.member.action.v1.dto.LogisticsCompanyCastor;
import com.yuexunit.finance.member.action.v1.model.LogisticsClerkDetail;
import com.yuexunit.finance.member.action.v1.model.LogisticsCompanyDetail;
import com.yuexunit.finance.member.action.v1.model.LogisticsCompanyInfo;
import com.yuexunit.finance.member.entity.LogisticsClerkEntity;
import com.yuexunit.finance.member.entity.LogisticsCompanyEntity;
import com.yuexunit.finance.member.service.LogisticsClerkService;
import com.yuexunit.finance.member.service.LogisticsCompanyService;
import com.yuexunit.finance.project.entity.DeliveryEntity;
import com.yuexunit.finance.project.entity.TallyingEntity;
import com.yuexunit.finance.project.entity.TransportNoticeEntity;
import com.yuexunit.finance.project.entity.lexicon.DeliveryStateEnum;
import com.yuexunit.finance.project.entity.lexicon.NoticeStateEnum;
import com.yuexunit.finance.project.entity.lexicon.TallyingStateEnum;
import com.yuexunit.finance.project.service.DeliveryService;
import com.yuexunit.finance.project.service.TallyingService;
import com.yuexunit.finance.project.service.TransportNoticeService;
import com.yuexunit.inject.ComponentFactory;
import com.yuexunit.inject.annotation.Implements;
import com.yuexunit.page.PageCriteria;
import com.yuexunit.page.PageList;
import com.yuexunit.persist.annotation.Transactional;
import com.yuexunit.tenant.TenantActionApi;
import com.yuexunit.tenant.dto.TenantIdOutput;

/**
 * @author wenwenlong
 */
@Implements(LogisticsCompanyActionApi.class)
public class LogisticsCompanyActionImpl implements LogisticsCompanyActionApi {

	private LogisticsCompanyService logisticsCompanyService = ComponentFactory.loadClass(LogisticsCompanyService.class);

	private LogisticsClerkService logisticsClerkService = ComponentFactory.loadClass(LogisticsClerkService.class);

	private AccountActionApi accountAction = ComponentFactory.loadClass(AccountActionApi.class);

	private AccountActionWebApi accountWebAction = ComponentFactory.loadClass(AccountActionWebApi.class);

	private TenantActionApi tenantAction = ComponentFactory.loadClass(TenantActionApi.class);
	
	private TallyingService tallyingService = ComponentFactory.loadClass(TallyingService.class);
	
	private TransportNoticeService transportNoticeService = ComponentFactory.loadClass(TransportNoticeService.class);
	
	private DeliveryService deliveryService = ComponentFactory.loadClass(DeliveryService.class);

	@Transactional
	@Override
	public String createLogisticsCompany(LogisticsCompanyInfo logisticsCompanyInfo) {
		LogisticsCompanyEntity entity = LogisticsCompanyCastor.fromLogisticsCompanyInfo(logisticsCompanyInfo);
		String accountName = logisticsCompanyInfo.getCompanyAccount();
		// 创建帐号
		AccountId account = accountAction.inquireAccountIdByAlias(accountName, AccountNameType.MOBILE.ordinal());
		if (account != null) {
			throw new BusinessException("该登陆号已被注册");
		}
		Long accountId = accountAction.createAccountSimple(accountName, "123456");
		AccountAlias accountAlias = new AccountAlias();
		accountAlias.setAccountId(accountId);
		accountAlias.setAccountName(accountName);
		accountAlias.setType(AccountNameType.MOBILE);
		accountAction.updateAccountAlias(accountAlias);
		// 创建租户信息
		TenantIdOutput tenantId = tenantAction.createTenantByAccountId(accountId, null);
		entity.setTenantId(tenantId.getTenantId());
		entity.setAccountId(accountId);
		return logisticsCompanyService.createLogisticsCompany(entity).toString();
	}

	@Transactional
	@Override
	public void updateLogisticsCompany(LogisticsCompanyDetail logisticsCompanyDetail) {
		LogisticsCompanyEntity entity = LogisticsCompanyCastor.fromLogisticsCompanyInfo(logisticsCompanyDetail, "createDateTime");
		logisticsCompanyService.updateLogisticsCompany(entity);
	}

	@Transactional
	@Override
	public void disableLogisticsCompany(Long companyId) {
		// 扣除 状态为 已完成/已上报
		Set<TallyingStateEnum> tallyStates = CollectionUtils.convertSet(TallyingStateEnum.values());
		tallyStates.remove(TallyingStateEnum.ALREADY_TALLY);
		tallyStates.remove(TallyingStateEnum.ALREADY_REPORT);
		List<TallyingEntity> tallings = tallyingService.inquireTallyingInProcess(companyId, tallyStates);
		
		// 扣除 状态为 已完成/已取消
		Set<NoticeStateEnum> noticeStates = CollectionUtils.convertSet(NoticeStateEnum.values());
		noticeStates.remove(NoticeStateEnum.CANCEL);
		noticeStates.remove(NoticeStateEnum.FINISHED);
		List<TransportNoticeEntity> notices = transportNoticeService.inquireTransportNoticeInProcess(companyId, noticeStates);
		
		// 扣除 状态为 已完成/已拒绝
		Set<DeliveryStateEnum> deliveryStates = CollectionUtils.convertSet(DeliveryStateEnum.values());
		deliveryStates.remove(DeliveryStateEnum.FINISHED);
		deliveryStates.remove(DeliveryStateEnum.REJECT);
		List<DeliveryEntity> deliveries = deliveryService.inqureDeliveryInProcess(companyId, deliveryStates);
		
		if (tallings.size() > 0 || notices.size() > 0 || deliveries.size() > 0) {
			throw new BusinessException("该物流公司中还有未完成任务，不能删除！");
		} else {
			logisticsCompanyService.disableLogisticsCompany(companyId);
		}
	}

	@Override
	public LogisticsCompanyDetail inquireLogisticsCompanyDetail(Long companyId) {
		LogisticsCompanyEntity entity = logisticsCompanyService.inquireLogisticsCompanyDetail(companyId);
		return LogisticsCompanyCastor.toLogisticsCompanyDetail(entity);
	}

	@Override
	public PageList<LogisticsCompanyDetail> inquireLogisticsCompanyList(String createDateTimeBegin, String createDateTimeEnd, String companyName, String companyAccount, Integer reportState, Integer effective, PageCriteria page) {
		Date beginDateTime = DateUtils.formatBeginDay(createDateTimeBegin);
		Date endDateTime = DateUtils.formatEndDay(createDateTimeEnd);
		PageList<LogisticsCompanyEntity> entityList = logisticsCompanyService.inquireLogisticsCompanyPageList(beginDateTime, endDateTime, companyName, companyAccount, reportState, effective, page);
		PageList<LogisticsCompanyDetail> details = new PageList<LogisticsCompanyDetail>(page, entityList.getTotalRecordCount());
		for (LogisticsCompanyEntity entity : entityList) {
			details.add(LogisticsCompanyCastor.toLogisticsCompanyDetail(entity));
		}
		return details;
	}
	
	@Override
	public List<LogisticsCompanyDetail> inquireLogisticsCompanyAll() {
		List<LogisticsCompanyEntity> entityList = logisticsCompanyService.inquireLogisticsCompanyList();
		List<LogisticsCompanyDetail> details = new ArrayList<LogisticsCompanyDetail>();
		for (LogisticsCompanyEntity entity : entityList) {
			details.add(LogisticsCompanyCastor.toLogisticsCompanyDetail(entity));
		}
		return details;
	}

	// ===============================================================================================================//
	@Override
	public String createLogisticsClerk(String clerkName, String clerkMobile) {
		LogisticsClerkEntity entity = LogisticsClerkCastor.fromLogisticsClerk(clerkName, clerkMobile);
		// 创建帐号
		AccountId account = accountAction.inquireAccountIdByAlias(clerkMobile, AccountNameType.MOBILE.ordinal());
		if (account != null) {
			System.err.println("clerkName:" + clerkName + " ===>>> " + account.getAccountId());
			throw new BusinessException("该手机号已被注册");
		}
		Long accountId = accountAction.createAccountSimple(clerkMobile, clerkMobile.substring(5));
		AccountAlias accountAlias = new AccountAlias();
		accountAlias.setAccountId(accountId);
		accountAlias.setAccountName(clerkMobile);
		accountAlias.setType(AccountNameType.MOBILE);
		accountAction.updateAccountAlias(accountAlias);

		tenantAction.createTenantAccount(FinanceSessionContext.getAccountTenantId(), accountId);
		entity.setAccountId(accountId);
		Long clerkId = logisticsClerkService.createLogisticsClerk(entity);
		return clerkId.toString();
	}

	@Override
	public void updateLogisticsClerk(Long clerkId, String clerkName, String clerkMobile) {
		LogisticsClerkEntity persist = logisticsClerkService.inqueryLogisticsClerkDetail(clerkId);
		LogisticsClerkEntity entity = LogisticsClerkCastor.fromLogisticsClerk(clerkName, clerkMobile);
		entity.setClerkId(clerkId);
		entity.setAccountId(persist.getAccountId());
		logisticsClerkService.updateLogisticsClerk(entity);
		if (persist.getClerkMobile().equals(clerkMobile)) {
			return;
		}
		// 修改帐号
		AccountId account = accountAction.inquireAccountIdByAlias(clerkMobile, AccountNameType.MOBILE.ordinal());
		if (account != null) {
			throw new BusinessException("该手机号已被注册");
		}

		Long accountId = persist.getAccountId();
		AccountAlias accountAlias = new AccountAlias();
		accountAlias.setAccountId(accountId);
		accountAlias.setAccountName(clerkMobile);
		accountAlias.setType(AccountNameType.MOBILE);
		accountAction.updateAccountAlias(accountAlias);
		accountWebAction.updateAccountInfo(accountId, clerkName, null, clerkMobile, null, null, null, null);
	}

	@Transactional
	@Override
	public void disableLogisticsClerk(Long clerkId) {
		LogisticsClerkEntity entity = logisticsClerkService.inqueryLogisticsClerkDetail(clerkId);
		// 删除登陆帐号
		List<String> accountNames = new ArrayList<>();
		accountNames.add(entity.getClerkMobile());
		accountAction.deleteAccountAlias(entity.getAccountId(), accountNames);

		entity.setAccountId(null);
		entity.setClerkMobile(null);
		logisticsClerkService.disableLogisticsClerk(entity);
	}

	@Override
	public LogisticsClerkDetail inquireLogisticsClerkDetail(Long clerkId) {
		LogisticsClerkEntity entity = logisticsClerkService.inqueryLogisticsClerkDetail(clerkId);
		return LogisticsClerkCastor.toLogisticsClerkDetail(entity);
	}

	@Override
	public PageList<LogisticsClerkDetail> inquireLogisticsClerkPageList(String clerkName, String clerkMobile, PageCriteria page) {
		System.out.println(clerkName);
		PageList<LogisticsClerkEntity> pageList = logisticsClerkService.inqueryLogisticsClerkList(FinanceSessionContext.getCompanyId(), clerkName, clerkMobile, page);
		PageList<LogisticsClerkDetail> resultList = new PageList<LogisticsClerkDetail>(page, pageList.getTotalRecordCount());
		for (LogisticsClerkEntity entity : pageList) {
			resultList.add(LogisticsClerkCastor.toLogisticsClerkDetail(entity));
		}
		return resultList;
	}

	@Override
	public PageList<LogisticsCompanyDetail> inquireLogisticsCompanyListByCompanyName(String companyName, PageCriteria page) {
		PageList<LogisticsCompanyEntity> entityList = logisticsCompanyService.inquireLogisticsCompanyListByCompanyName(companyName, page);
		PageList<LogisticsCompanyDetail> details = new PageList<LogisticsCompanyDetail>(page, entityList.getTotalRecordCount());
		for (LogisticsCompanyEntity entity : entityList) {
			details.add(LogisticsCompanyCastor.toLogisticsCompanyDetail(entity));
		}
		return details;
	}

	@Override
	public void inquireLogisticsCompanyValid(String accountName) {
		AccountId account = accountAction.inquireAccountIdByAlias(accountName, AccountNameType.MOBILE.ordinal());
		if(account==null){
			throw new BusinessException("该账号不存在此系统");
		}
		TenantIdOutput tenantIdOutput = tenantAction.inquireTenantByAccountId(account.getAccountId());
		 LogisticsCompanyEntity  companyEntity = logisticsCompanyService.inquireTenantLogisticsCompany(tenantIdOutput.getTenantId());
		if(!companyEntity.getEffective()){
			throw new BusinessException("该物流公司账号被禁用");
		}
	}
}
